﻿using ReadNovel.API.Response;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Text;
using System.Windows;

namespace ReadNovel.API
{
    public class DefaultClient
    {

        private void DoResponse<T>(WebExceptionStatus status, string msg, Action<T> callBack) where T : IResponse
        {
            if (status == WebExceptionStatus.Success)
            {
                ParseToObj<T>(msg, callBack);
            }
            else
            {
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    G.Navigate.PhoneApplicationPageHelp.GetBasePage().ShowState(string.Format("{0}:{1}", status.ToString(), msg));
                });
                T rsp = Activator.CreateInstance<T>();
                rsp.ErrorMessage = string.Format("{0}:{1}", status.ToString(), msg);
                rsp.Body = msg;
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    callBack(rsp);
                });

            }
        }

        public void Execute<T>(Request.BaseRequest<T> request, Action<T> callBack) where T : IResponse
        {
            string url = string.Format("{0}{1}", APIConfig.BaseURL, request.GetPath());
            var dic = request.GetParameters();
            dic.Add("a", request.Action);
            dic.Add("data", "json");
            dic.Add("ct", "android");
            dic.Add("v", "1");
            G.Net.HttpGet get = new G.Net.HttpGet(url);
            foreach (var item in dic)
            {
                if (!string.IsNullOrEmpty(item.Value))
                    get.Params.Add(item.Key, HttpUtility.UrlEncode(item.Value));
            }
            get.Request((s, msg) =>
            {
                DoResponse<T>(s, msg, callBack);
            });
        }
        /// <summary>
        /// 组装普通文本请求参数。
        /// </summary>
        /// <param name="parameters">Key-Value形式请求参数字典</param>
        /// <returns>URL编码后的请求数据</returns>
        public byte[] BuildQuery(IDictionary<string, string> parameters)
        {
            StringBuilder postData = new StringBuilder();
            bool hasParam = false;
            IEnumerator<KeyValuePair<string, string>> dem = parameters.GetEnumerator();
            while (dem.MoveNext())
            {
                string name = dem.Current.Key;
                string value = dem.Current.Value;
                // 忽略参数名或参数值为空的参数
                if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
                {
                    if (hasParam)
                    {
                        postData.Append("&");
                    }
                    postData.Append(name);
                    postData.Append("=");
                    postData.Append(Uri.EscapeDataString(value));
                    hasParam = true;
                }
            }
            Debug.WriteLine("PostData");
            Debug.WriteLine(postData.ToString());
            return System.Text.Encoding.UTF8.GetBytes(postData.ToString());
        }

        private void ParseToObj<T>(string body, Action<T> callBack) where T : IResponse
        {
            T rsp = default(T);
            try
            {

                rsp = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(body);

                //rsp = G.Utils.SerializerHelp.JsonDeserialize<T>(body);
                rsp.Body = body;
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    callBack(rsp);
                });
            }
            catch (Exception ex)
            {
                if (rsp == null)
                {
                    rsp = Activator.CreateInstance<T>();
                }
                rsp.ErrorMessage = "数据解析出错" + ex.Message;
                rsp.Body = body;
                Deployment.Current.Dispatcher.BeginInvoke(() =>
                {
                    callBack(rsp);
                });
            }

        }
    }
}
